home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Windows 95 Programs / Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso / 0850 / wspi_src.zip / WS_PING.C < prev    next >
C/C++ Source or Header  |  1994-01-23  |  19KB  |  600 lines

  1. /*************************************************************************
  2.  Windows Sockets PING Client Application
  3.  
  4.  Written by John A. Junod, 267 Hillwood St., Martinez, GA, 30907 93.10.01
  5.  <junodj@css583.gordon.army.mil> <zj8549@trotter.usma.edu>   C$:72321,366
  6.  
  7.  Released into the public domain with no restrictions other than to give
  8.  me some of the credit if you use this code in other applications.  Some
  9.  code concepts based on code published in UNIX Network Programming by
  10.  W. Richard Stevens or on BSD networking source code.
  11.  
  12.  Note that MOST Windows Sockets DLL's do not support RAW_SOCKETS.  This
  13.  does work with Trumpet's Windows Sockets DLL Alpha 18.
  14.  
  15.  Purpose of this program was to see how a PING program could be implemented
  16.  under Windows Sockets.  This program uses either blocking or async
  17.  socket calls to perform its magic.  
  18. *************************************************************************/
  19.  
  20. //----------------------
  21. #include "ws_glob.h"
  22. #include "WS_ping.H"
  23. #include "ip_icmp.h"
  24. //----------------------
  25.  
  26. BOOL bSpecified=FALSE;
  27.  
  28. int nPktLength=50;
  29. int nNumPkts=10;
  30. int nTimeOut=10;
  31. extern int nTransmitted,nReceived;
  32.  
  33. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  34.                    LPSTR lpszCmdLine, int nCmdShow)
  35. {
  36.   MSG        msg;           // MSG structure to store your messages
  37.   int        nRc;           // return value from Register Classes
  38.   long       nWndunits;     // window units for size and location
  39.   int        nX;            // the resulting starting point (x, y)
  40.   int        nY;
  41.   int        nWidth;        // the resulting width and height for this
  42.   int        nHeight;       // window
  43.   int        err;
  44.  
  45.   strcpy(szAppName, "WS_PING");
  46.   hInst = hInstance;
  47.   if(!hPrevInstance)
  48.   {
  49.     if ((nRc = nCwRegisterClasses()) == -1)
  50.     {
  51.       MessageBox(NULL, "Window creation failed", NULL, MB_ICONEXCLAMATION);
  52.       return nRc;    
  53.     }
  54.   }
  55.  
  56.   // Create a device independant size and location
  57.   nWndunits = GetDialogBaseUnits();
  58.   nWndx = LOWORD(nWndunits);
  59.   nWndy = HIWORD(nWndunits);
  60.   nX = ((18 * nWndx) / 4);
  61.   nY = ((18 * nWndy) / 8);
  62.   nWidth = ((247 * nWndx) / 4);
  63.   nHeight = ((218 * nWndy) / 8);
  64.  
  65.   // create application's Main window
  66.   hWndMain = CreateWindow(
  67.     szAppName, "WinSock_PING",
  68.     WS_CAPTION     | WS_SYSMENU    | WS_MINIMIZEBOX  |
  69.     WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN | WS_OVERLAPPED,
  70.     nX,nY, nWidth, nHeight,
  71.     NULL, NULL, hInst,  NULL);
  72.  
  73.   if(hWndMain == NULL)
  74.   {
  75.     MessageBox(NULL, "Error registering class", NULL, MB_ICONEXCLAMATION);
  76.     return 2;
  77.   }
  78.  
  79.   if(lstrlen((LPSTR)lpszCmdLine)>0) {
  80.     bSpecified=TRUE;
  81.     strcpy(szRemoteHost,lpszCmdLine);
  82.   }
  83.  
  84.   if (err = WSAStartup( 0x0101, &WSAData))  // register task with
  85.   {                                         // winsock tcp/ip API
  86.     ReportWSError(err);            
  87.   } else {
  88.     GetLocalInfo();
  89.     ShowWindow(hWndMain, nCmdShow);         // display main window
  90.     while(GetMessage(&msg, NULL, 0, 0))     // Until WM_QUIT message
  91.     {
  92.       TranslateMessage(&msg);
  93.       DispatchMessage(&msg);
  94.     }
  95.     WSACleanup();
  96.     ReleaseDisplayMem();
  97.   }
  98.   // Do clean up before exiting from the application
  99.   CwUnRegisterClasses();
  100.   return msg.wParam;
  101. }
  102.  
  103. #define WM_RESETCURSOR WM_USER+10
  104.  
  105. // Main window message processing
  106. LONG FAR PASCAL WndProc(HWND hWnd,WORD Message,WORD wParam,LONG lParam)
  107. {
  108.   int nIndex,nRC,nBytesRecv;
  109.   static int saFromAddrLen;
  110.   static struct sockaddr_in saDestAddr;
  111.   static struct sockaddr_in saFromAddr;
  112.   static struct hostent  HostEntry , *pHostEntry;
  113.   static struct protoent ProtoEntry, *pProtoEntry;
  114.   static HANDLE hATHhost;
  115.   static HANDLE hATHprot;
  116.  
  117.   switch (Message)
  118.   {
  119.     case WM_CREATE:
  120.       hStdCursor=LoadCursor(NULL,IDC_ARROW);
  121.       hWaitCursor=LoadCursor(NULL,IDC_WAIT);
  122.       if(!bSpecified)
  123.         GetPrivateProfileString("WS_PING", "HOSTNAME",
  124.           "129.29.64.246",szRemoteHost,79,szIniFile);
  125.       else
  126.         PostMessage(hWnd,WM_COMMAND,IDM_ASYNC_CONNECT,0L);
  127.       break;
  128.  
  129.     case WM_TIMER:
  130.       switch(wParam) {
  131.         case 10:
  132.           DoPrintf("[Timer-TIMEOUT] ");
  133.           KillTimer(hWnd,10);
  134.           if(WSAIsBlocking()) {
  135.             bAborted=TRUE;
  136.             WSACancelBlockingCall();
  137.           }
  138.           break;
  139.  
  140.         case 20:
  141.           DoPrintf("[Timer-ASYNC_SEND] ");
  142.           if(nTransmitted<nNumPkts) {
  143.             send_ping(ping_socket,&saDestAddr,szMsgBuf,
  144.                       nPktLength+SIZE_ICMP_HDR);
  145.             PostMessage(hWnd,WM_PING_RECEIVE,0,0l);
  146.           } else {
  147.             KillTimer(hWnd,20);
  148.             if(nReceived!=nTransmitted)
  149.               SendMessage(hWnd,WM_PING_RECEIVE,0,0l);
  150.             PostMessage(hWnd,WM_PING_FINISH,0,0l);
  151.           }
  152.           break;
  153.  
  154.         case 30:
  155.           DoPrintf("[Timer-BLOCK_SEND] ");
  156.           if(nTransmitted<nNumPkts)
  157.           {
  158.             if(send_ping(ping_socket,&saDestAddr,szMsgBuf,
  159.                       nPktLength+SIZE_ICMP_HDR))
  160.               recv_ping(ping_socket,szString,TRUE);
  161.           }
  162.           else {
  163.             KillTimer(hWnd,30);
  164.             if(nReceived!=nTransmitted)
  165.               recv_ping(ping_socket,szString,TRUE);
  166.             PostMessage(hWnd,WM_PING_FINISH,0,0l);
  167.           }
  168.           break;
  169.  
  170.         default:
  171.           KillTimer(hWnd,wParam);
  172.           break;
  173.       }
  174.       break;
  175.     case WM_COMMAND:
  176.       if(wParam==IDM_CLOSE || wParam==IDM_EXIT) {
  177.         if(ping_socket!=INVALID_SOCKET) {
  178.           ping_socket=DoClose(ping_socket);
  179.           SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  180.         }
  181.         if(wParam==IDM_EXIT)
  182.           SendMessage(hWnd,WM_CLOSE,0,0L);
  183.         break;
  184.       } else if(bCmdInProgress) return(FALSE);
  185.       switch (wParam)
  186.       {
  187.         case IDM_ASYNC_CONNECT:
  188.           bCmdInProgress=1;
  189.           if(!bSpecified)
  190.             { FARPROC lpfnMsgProc;
  191.               lpfnMsgProc=MakeProcInstance((FARPROC)WS_HostMsgProc,hInst);
  192.               DialogBox(hInst,(LPSTR)"DLG_HOST",hWnd,lpfnMsgProc);
  193.               FreeProcInstance(lpfnMsgProc);
  194.             }
  195.           bSpecified=FALSE;
  196.           memset(&saDestAddr,0,sizeof(struct sockaddr_in));
  197.           memset(&HostEntry,0,sizeof(struct hostent));
  198.           memset(&ProtoEntry,0,sizeof(struct protoent));
  199.           saDestAddr.sin_family=AF_INET;
  200.           if((saDestAddr.sin_addr.s_addr=inet_addr(szRemoteHost))==INADDR_NONE)
  201.             hATHhost=WSAAsyncGetHostByName(hWnd,WM_PING_HOST,szRemoteHost,
  202.                         szMsgBuf,MAXGETHOSTSTRUCT);
  203.           else hATHhost=0;
  204.           hATHprot=WSAAsyncGetProtoByName(hWnd,WM_PING_PROTO,"icmp",
  205.                         &szMsgBuf[MAXGETHOSTSTRUCT],MAXGETHOSTSTRUCT);
  206.           break;
  207.  
  208.         case IDM_LOOKUP:
  209.           bCmdInProgress=1;
  210.           if(!bSpecified)
  211.             { FARPROC lpfnMsgProc;
  212.               lpfnMsgProc=MakeProcInstance((FARPROC)WS_HostMsgProc,hInst);
  213.               DialogBox(hInst,(LPSTR)"DLG_HOST",hWnd,lpfnMsgProc);
  214.               FreeProcInstance(lpfnMsgProc);
  215.             }
  216.           bSpecified=FALSE;
  217.           memset(&saDestAddr,0,sizeof(struct sockaddr));
  218.           saDestAddr.sin_family=AF_INET;
  219.           DoPrintf(" ");
  220.           
  221.           if((saDestAddr.sin_addr.s_addr=inet_addr(szRemoteHost))==INADDR_NONE) {
  222.             if(!(pHostEntry=gethostbyname(szRemoteHost))) {
  223.               DoPrintf("can't get \"%s\" host entry.",szRemoteHost);
  224.               SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  225.               bCmdInProgress=0;
  226.               break;
  227.             }
  228.           } else {
  229.             if(!(pHostEntry=gethostbyaddr((LPSTR)&saDestAddr.sin_addr.s_addr,
  230.                 4,PF_INET))) {
  231.               DoPrintf("can't get \"%s\" ip entry.",szRemoteHost);
  232.               goto skipit;
  233.             }
  234.           }
  235.           {
  236.             struct in_addr *iptr;
  237.             LPSTR lptr;
  238.             int nCount=0;
  239.               memcpy(&saDestAddr.sin_addr,pHostEntry->h_addr,
  240.                      pHostEntry->h_length);
  241.               DoPrintf("Official Name: %s",pHostEntry->h_name);
  242.               while((iptr=(struct in_addr *)*(pHostEntry->h_addr_list))!=NULL) {
  243.                 DoPrintf("IP Address: %s",inet_ntoa(*iptr));
  244.                 pHostEntry->h_addr_list++;
  245.               }
  246.               while((lptr=(LPSTR)*(pHostEntry->h_aliases))!=NULL) {
  247.                 if(nCount++<1) DoPrintf("Aliases:");
  248.                 DoPrintf("         %s",lptr);
  249.                 pHostEntry->h_aliases++;
  250.               }
  251.           }
  252. skipit:
  253.           bCmdInProgress=0;
  254.           SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  255.           break;
  256.  
  257.        case IDM_CONNECT:
  258.           bCmdInProgress=1;
  259.           if(!bSpecified)
  260.             { FARPROC lpfnMsgProc;
  261.               lpfnMsgProc=MakeProcInstance((FARPROC)WS_HostMsgProc,hInst);
  262.               DialogBox(hInst,(LPSTR)"DLG_HOST",hWnd,lpfnMsgProc);
  263.               FreeProcInstance(lpfnMsgProc);
  264.             }
  265.           bSpecified=FALSE;
  266.           memset(&saDestAddr,0,sizeof(struct sockaddr));
  267.           saDestAddr.sin_family=AF_INET;
  268.           
  269.           if((saDestAddr.sin_addr.s_addr=inet_addr(szRemoteHost))==INADDR_NONE) {
  270.             if(!(pHostEntry=gethostbyname(szRemoteHost))) {
  271.               DoPrintf("can't get \"%s\" host entry.",szRemoteHost);
  272.               SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  273.               bCmdInProgress=0;
  274.               break;
  275.             } else {
  276.               memcpy((char *)&saDestAddr.sin_addr,pHostEntry->h_addr,
  277.                   pHostEntry->h_length);
  278.             }
  279.           }
  280. /*
  281.           if((pProtoEntry=getprotobyname("icmp"))==NULL) {
  282.             bCmdInProgress=0;
  283.             DoPrintf("unknown protocol: icmp");
  284.             SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  285.             break; 
  286.           }
  287.           justing using a 1 in here now
  288. */
  289.           if((ping_socket=socket(saDestAddr.sin_family,SOCK_RAW,1))
  290.              ==INVALID_SOCKET)
  291.           {
  292.             DoPrintf("can't create raw socket %s",
  293.                       ReturnWSError(WSAGetLastError(),NULL));
  294.             SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  295.             break;
  296.           }
  297.           nTransmitted=0; nReceived=0;
  298.           DoPrintf("[%u] raw socket created",ping_socket);
  299.           PrintHeader(&saDestAddr,nPktLength);
  300.           SetTimer(hWnd,30,1000,NULL);
  301.           break;
  302.  
  303.         case IDM_ABOUT:
  304.           { FARPROC lpfnMsgProc;
  305.             lpfnMsgProc = MakeProcInstance((FARPROC)WS_AboutMsgProc, hInst); 
  306.             DialogBox(hInst, (LPSTR)"DLG_ABOUT", hWnd, lpfnMsgProc);
  307.             FreeProcInstance(lpfnMsgProc);
  308.           }
  309.           break;
  310.  
  311.         default:
  312.           return DefWindowProc(hWnd, Message, wParam, lParam);
  313.       }
  314.       break;
  315.  
  316.     case WM_PING_HOST:
  317.       DoPrintf("[WM_PING_HOST] ");
  318.       if(WSAGETASYNCERROR(lParam)!=0) {
  319.         ReportWSError(WSAGETASYNCERROR(lParam));
  320.         SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  321.       } else {
  322.         memcpy(&HostEntry,szMsgBuf,sizeof(struct hostent));
  323.         memcpy(&saDestAddr.sin_addr,HostEntry.h_addr,HostEntry.h_length);
  324.         hATHhost=0;
  325.         if(hATHprot==0) SendMessage(hWnd,WM_PING_CAS,0,0l);
  326.       }
  327.       break;
  328.  
  329.     case WM_PING_PROTO:
  330.       DoPrintf("[WM_PING_PROTO] ");
  331.       if(WSAGETASYNCERROR(lParam)!=0) {
  332.         ReportWSError(WSAGETASYNCERROR(lParam));
  333.         SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  334.       } else {
  335.         memcpy(&ProtoEntry,&szMsgBuf[MAXGETHOSTSTRUCT],
  336.                      sizeof(struct protoent));
  337.         hATHprot=0;
  338.         if(hATHhost==0) SendMessage(hWnd,WM_PING_CAS,0,0l);
  339.       }
  340.       break;
  341.  
  342.     case WM_PING_CAS:
  343.       PrintHeader(&saDestAddr,nPktLength+SIZE_ICMP_HDR);
  344.       ping_socket=socket(saDestAddr.sin_family,SOCK_RAW,
  345.                     ProtoEntry.p_proto);
  346.       if(ping_socket==INVALID_SOCKET) {
  347.         DoPrintf("can't create raw socket: %s",
  348.                     ReturnWSError(WSAGetLastError(),NULL));
  349.         SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  350.       } else {
  351.         if(WSAAsyncSelect(ping_socket,hWnd,WM_PING_RECEIVE,FD_READ)
  352.             ==SOCKET_ERROR)
  353.         {
  354.           DoPrintf("asyncselect: %s",ReturnWSError(WSAGetLastError(),NULL));
  355.           ping_socket=DoClose(ping_socket);
  356.           SendMessage(hWnd,WM_RESETCURSOR,0,0l);
  357.         } else {
  358.           nTransmitted=nReceived=0;
  359.           SetTimer(hWndMain,20,1000,NULL);
  360.         }
  361.       }
  362.       break;
  363.  
  364.     case WM_PING_RECEIVE:
  365.       DoPrintf("[WM_PING_RECEIVE] ");
  366.       saFromAddrLen=sizeof(struct sockaddr);
  367.       nBytesRecv=recvfrom(ping_socket,szString,MAXPACKET,0,
  368.                 (struct sockaddr *)&saFromAddr,
  369.                 &saFromAddrLen);
  370.       if(nBytesRecv!=SOCKET_ERROR || WSAGetLastError()!=WSAEINTR) {
  371.         if(nBytesRecv==SOCKET_ERROR) {
  372.           DoPrintf("[recvfrom] %s",ReturnWSError(WSAGetLastError(),NULL));
  373.         } else PrintPkt(szString,nBytesRecv,&saFromAddr,TRUE);
  374.       }
  375.       break;
  376.  
  377.     case WM_PING_FINISH:
  378.       ping_socket=DoClose(ping_socket);
  379.       PrintStats();
  380.  
  381.     case WM_RESETCURSOR:
  382.       bCmdInProgress=0;
  383.       SetCursor(hStdCursor);
  384.       break;
  385.  
  386.     case WM_SETCURSOR:
  387.       if(bCmdInProgress)
  388.         SetCursor(hWaitCursor);
  389.       else
  390.         return DefWindowProc(hWnd, Message, wParam, lParam);
  391.       break;
  392.  
  393.     case WM_PAINT:  // code for the window's client area
  394.       DoPaint(hWnd);
  395.       break;
  396.  
  397.     case WM_VSCROLL:
  398.       switch(wParam)
  399.       {
  400.         case SB_LINEDOWN:
  401.           if(sVPos<(ptrhGMem-1)) sVPos++;
  402.           break;
  403.         case SB_LINEUP:
  404.           if(sVPos>0) --sVPos;
  405.           break;
  406.         case SB_THUMBPOSITION:
  407.           sVPos = min(ptrhGMem, LOWORD(lParam));
  408.           break;
  409.         case SB_PAGEUP:
  410.           if(sVPos>10) sVPos-=10; else sVPos=0;
  411.           break;
  412.         case SB_PAGEDOWN:
  413.           if(sVPos<(ptrhGMem-10)) sVPos+=10; else sVPos=ptrhGMem;
  414.           break;
  415.         default:
  416.           return FALSE;
  417.       }
  418.       SetScrollPos(hWnd,SB_VERT,sVPos,TRUE);
  419.       InvalidateRect(hWnd,NULL,TRUE);
  420.       break;
  421.  
  422.     case WM_CLOSE:  // close the window
  423.       // Destroy child windows, modeless dialogs, then, this window
  424.       if (hWnd == hWndMain) {
  425.         if(ping_socket!=INVALID_SOCKET)
  426.           ping_socket=DoClose(ping_socket);
  427.         DestroyWindow(hWnd);
  428.         WritePrivateProfileString("WS_PING", "HOSTNAME",szRemoteHost,
  429.                      szIniFile);
  430.         PostQuitMessage(0);  // Quit the application
  431.       } else
  432.         DestroyWindow(hWnd);
  433.       break;
  434.  
  435.     default:
  436.       return DefWindowProc(hWnd, Message, wParam, lParam);
  437.   }
  438.   return 0L;
  439. } // End of WndProc
  440.  
  441. /************************************************************************/
  442. /* Misc Dialog Window Procedures                                        */
  443. /************************************************************************/
  444. BOOL FAR PASCAL WS_AboutMsgProc(HWND hWndDlg, WORD Message, 
  445.                                 WORD wParam, LONG lParam)
  446.  switch(Message)
  447.  {
  448.    case WM_INITDIALOG:
  449.      cwCenter(hWndDlg, 0);
  450.      break;
  451.    case WM_CLOSE:
  452.      PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  453.      break;
  454.    case WM_COMMAND:
  455.      switch(wParam)
  456.      {
  457.        case IDOK:
  458.          EndDialog(hWndDlg, TRUE);
  459.          break;
  460.        case IDCANCEL:
  461.          EndDialog(hWndDlg, FALSE);
  462.          break;
  463.      }
  464.      break;
  465.     default:
  466.         return FALSE;
  467.   }
  468.   return TRUE;
  469. }
  470.  
  471. BOOL FAR PASCAL WS_HostMsgProc(HWND hWndDlg, WORD Message,
  472.                                 WORD wParam, LONG lParam)
  473. {
  474.   BOOL lpfTranslated;
  475.    
  476.   switch(Message)
  477.   {
  478.     case WM_INITDIALOG:
  479.       SetDlgItemText(hWndDlg,DLG_HOST_NAME,szRemoteHost);
  480.       SetDlgItemInt(hWndDlg,DLG_HOST_NUMPKTS,nNumPkts,FALSE);
  481.       SetDlgItemInt(hWndDlg,DLG_HOST_PKTLENGTH,nPktLength,FALSE);
  482.       SetDlgItemInt(hWndDlg,DLG_HOST_TIMEOUT,nTimeOut,FALSE);
  483.       CheckDlgButton(hWndDlg,DLG_HOST_VERBOSE,bVerbose);
  484.       cwCenter(hWndDlg, 0);
  485.       break;
  486.     case WM_CLOSE:
  487.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  488.       break;
  489.     case WM_COMMAND:
  490.       switch(wParam)
  491.       {
  492.         case IDOK:
  493.           GetDlgItemText(hWndDlg,DLG_HOST_NAME,szRemoteHost,70);
  494.           nNumPkts=GetDlgItemInt(hWndDlg,DLG_HOST_NUMPKTS,
  495.                              &lpfTranslated,FALSE);
  496.           nPktLength=GetDlgItemInt(hWndDlg,DLG_HOST_PKTLENGTH,
  497.                              &lpfTranslated,FALSE);
  498.           nTimeOut=GetDlgItemInt(hWndDlg,DLG_HOST_TIMEOUT,
  499.                              &lpfTranslated,FALSE);
  500.           bVerbose=IsDlgButtonChecked(hWndDlg,DLG_HOST_VERBOSE);
  501.           if((nPktLength+SIZE_ICMP_HDR)>512) nPktLength=512-SIZE_ICMP_HDR;
  502.           EndDialog(hWndDlg, TRUE);
  503.           break;
  504.         case IDCANCEL:
  505.           EndDialog(hWndDlg, FALSE);
  506.           break;
  507.       }
  508.       break;
  509.     default:
  510.       return FALSE;
  511.   }
  512.   return TRUE;
  513. }
  514.  
  515. BOOL FAR PASCAL WS_InputMsgProc(HWND hWndDlg, WORD Message,
  516.                                 WORD wParam, LONG lParam)
  517.   switch(Message)
  518.   {
  519.     case WM_INITDIALOG:
  520.       SetDlgItemText(hWndDlg,DLG_PROMPT,szDlgPrompt);
  521.       SetDlgItemText(hWndDlg,DLG_EDIT,szDlgEdit);
  522.       cwCenter(hWndDlg, 0);
  523.       break;
  524.     case WM_CLOSE:
  525.       PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  526.       break;
  527.     case WM_COMMAND:
  528.       switch(wParam)
  529.       {
  530.         case IDOK:
  531.           GetDlgItemText(hWndDlg,DLG_EDIT,szDlgEdit,70);
  532.           EndDialog(hWndDlg, TRUE);
  533.           break;
  534.         case IDCANCEL:
  535.           EndDialog(hWndDlg, FALSE);
  536.           break;
  537.       }
  538.       break;
  539.     default:
  540.       return FALSE;
  541.   }
  542.   return TRUE;
  543. }
  544.  
  545. int nCwRegisterClasses(void)
  546. {
  547.   WNDCLASS   wndclass;    // struct to define a window class
  548.   memset(&wndclass, 0x00, sizeof(WNDCLASS));
  549.  
  550.   wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW;
  551.   wndclass.lpfnWndProc = WndProc;
  552.   wndclass.cbClsExtra = 0;
  553.   wndclass.cbWndExtra = 0;
  554.   wndclass.hInstance = hInst;
  555.   wndclass.hIcon = LoadIcon(hInst, "WS_PING");
  556.   wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  557.   wndclass.hbrBackground = (HBRUSH) CreateSolidBrush(RGB(192, 192, 192));
  558.   wndclass.lpszMenuName = szAppName;
  559.   wndclass.lpszClassName = szAppName;
  560.   if(!RegisterClass(&wndclass))
  561.     return -1;
  562.   return(0);
  563. }
  564.  
  565. void cwCenter(hWnd, top)
  566. HWND hWnd;
  567. int top;
  568. {
  569.   POINT      pt;
  570.   RECT       swp;
  571.   RECT       rParent;
  572.   int        iwidth;
  573.   int        iheight;
  574.  
  575.   GetWindowRect(hWnd, &swp);
  576.   GetClientRect(hWndMain, &rParent);
  577.   iwidth = swp.right - swp.left;
  578.   iheight = swp.bottom - swp.top;
  579.   pt.x = (rParent.right - rParent.left) / 2;
  580.   pt.y = (rParent.bottom - rParent.top) / 2;
  581.   ClientToScreen(hWndMain, &pt);
  582.   pt.x = pt.x - (iwidth / 2);
  583.   pt.y = pt.y - (iheight / 2);
  584.   if(top)
  585.     pt.y = pt.y + top;
  586.   MoveWindow(hWnd, pt.x, pt.y, iwidth, iheight, FALSE);
  587. }
  588.  
  589. void CwUnRegisterClasses(void)
  590. {
  591.   WNDCLASS   wndclass;
  592.   memset(&wndclass, 0x00, sizeof(WNDCLASS));
  593.   GetClassInfo(hInst, szAppName, &wndclass);
  594.   DeleteObject(wndclass.hbrBackground);
  595.   UnregisterClass(szAppName, hInst);
  596. }
  597.  
  598.